專案中如果有檔案下載與上傳的功能,我們會希望user不要輸入一些奇怪的資料,讓系統發生非預期的行為,而Apache POI可以讓我們對Cell設定規範,能夠防止user在Cell中輸入範圍之外的資料。
首先來介紹一下DataValidation相關的類別:
DataValidationHelper
是用來建立和管理資料驗證規則的工具,讓我們生成各種類型的資料驗證。
DataValidationConstraint
(驗證約束)和 DataValidation
(資料驗證)。能夠創建不同類型的驗證規則,比如數值範圍驗證、日期驗證、下拉選單驗證等。DataValidationConstraint
定義了具體的驗證條件,用來設定Cell中允許的輸入條件與資料驗證的邏輯。
DataValidationConstraint
設定具體的限制條件,如允許哪些數值、字串或日期範圍等。DataValidation
將驗證條件應用到某一範圍的Cell上。
我繼續對學生成績資料表做一些資料驗證的設定:
// 建立Workbook
Workbook workbook = new XSSFWorkbook();
// 建立excel sheet(參數為sheetname)
Sheet sheet = workbook.createSheet("學生考試成績表");
sheet.setDefaultColumnWidth(10);
// 設定Cell的驗證
this.setDataValidation(sheet);
// 以下略...
在setDataValidation()
方法中可以看到我設定驗證的步驟:
createExplicitListConstraint()
方法能建立資料範圍的下拉選單、createIntegerConstraint()
能建立整數的資料範圍、createDateConstraint()
能建立日期的資料範圍
createDateConstraint()
第一個參數是設定驗證邏輯,第二、三個參數是日期範圍,由於範例中我的驗證邏輯是「大於等於2022/01/01」,第三個參數才會是null。如果驗證邏輯改為DataValidationConstraint.OperatorType.BETWEEN
,第三個參數就需要輸入了createDateConstraint()
第二、三個參數需要以"Date(yyyy, MM, dd)"
這個格式表示,不然驗證會失效
createDateConstraint()
第四個參數可以輸入要顯示的日期格式"yyyy/MM/dd"
CellRangeAddressList()
設定驗證的Cell範圍,用法與CellRangeAddress()
相同,我希望這個sheet的驗證欄位整行都要適用,因此第二個參數輸入XSSFWorkbook中Row最大的indexcreateValidation()
將驗證條件應用到設定的範圍上private void setDataValidation(Sheet sheet) {
// 1. 取得 DataValidationHelper 來幫助設置驗證
DataValidationHelper validationHelper = sheet.getDataValidationHelper();
// 2. 設定年級驗證條件
// 年級欄位選項清單
DataValidationConstraint gradeConstraint = validationHelper.createExplicitListConstraint(new String[] {"1", "2", "3", "4"});
// 分數範圍驗證條件
DataValidationConstraint scoreConstraint = validationHelper.createIntegerConstraint(
DataValidationConstraint.OperatorType.BETWEEN, "0", "100");
// 考試日期驗證條件
DataValidationConstraint dateConstraint = validationHelper.createDateConstraint(
DataValidationConstraint.OperatorType.GREATER_OR_EQUAL, "Date(2022, 0, 1)", null, "yyyy/MM/dd");
// 3. 設置驗證範圍
// 表示第3行,第3列到最後列
CellRangeAddressList gradeAddressList = new CellRangeAddressList(2, 1048575, 2, 2);
// 表示第5行,第3列到最後列
CellRangeAddressList scoreAddressList = new CellRangeAddressList(2, 1048575, 5, 5);
// 表示第7行,第3列到最後列
CellRangeAddressList dateAddressList = new CellRangeAddressList(2, 1048575, 6, 6);
// 4. 建立資料驗證
DataValidation gradeValidation = validationHelper.createValidation(gradeConstraint, gradeAddressList);
DataValidation integerValidation = validationHelper.createValidation(scoreConstraint, scoreAddressList);
DataValidation dateValidation = validationHelper.createValidation(dateConstraint, dateAddressList);
// 5. 設置顯示提示框
gradeValidation.setShowErrorBox(true);
gradeValidation.createErrorBox("資料錯誤", "請選擇下拉選單範圍內的值");
integerValidation.setShowErrorBox(true);
integerValidation.createErrorBox("資料錯誤", "請輸入0~100正整數");
dateValidation.setShowErrorBox(true);
dateValidation.createErrorBox("資料錯誤", "請輸入2020/01/01之後的有效日期");
// 6. 將資料驗證套用到工作表
sheet.addValidationData(gradeValidation);
sheet.addValidationData(integerValidation);
sheet.addValidationData(dateValidation);
}
匯出的excel看起來沒什麼不同:
當我們想在年級輸入超過範圍的數值時,就會跳出訊息。
並且能夠由下拉選單選擇符合的範圍。
要在成績以及考試日期欄位輸入超過範圍的數值,也是一樣會顯示提示訊息。
甚至日期的驗證還能擋掉一些不正常的日期。
這個功能算是滿容易設定而且方便的,可以初步阻擋一些不符合的資料,再搭配後端驗證就能夠將非預期資料造成的錯誤機率降得更低了。